package GameEngine.gui;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import GameEngine.Pentagorun;

import java.net.*;
import java.util.Observable;
import java.util.Observer;
import java.applet.*;

public class Pentago extends Observable implements Observer
{
	private static final long serialVersionUID = 1L;
	private String [] gameMode = {"Min/Max" , "AlphaBetaPruning"};
	private DrawingPanel drawingArea;
	private JFrame settings, gameFrame;
	private JRadioButton pvp,pvc,cvc;
	private ButtonGroup choice;
	private JPanel choicePan,buttonPan;
	private JButton submitSettings,exitSettings;
	private JComboBox<String> iaChoice;
	private Board gameBoard;
	boolean currentPlayer;
	private int rotatingQuad,direction, angle,gameType; // game type possible values: 0 (pVp), 1 (pVc),2(pVp
	private int gameEndStatus,rotationCount;// 0 = win, 1=loss,2=tie
	private boolean needToRotate,gameOver,gameOn;
	private String gameStatus;
	private Point start;
	private Image[] images;
	private Image[] gameOverImages;
	private Image quads,quads2;
	private final boolean BLACK = true;
	private final boolean RED = false;
	private final int RIGHT = 1;
	private final int LEFT = -1;
	private final int NO_ROTATING_QUAD = -1;
	private final int errorIndexImage=5;
	private int mode;
	private Pentagorun gameLogic;

	public Pentago()
	{
		gameFrame= new JFrame("Pentago");
		gameFrame.setResizable(true);
		gameFrame.setSize(new Dimension(640,480));
		gameFrame.setLocation(120, 20);
		gameFrame.setIconImage(new ImageIcon("gameIcon.png").getImage());
		
		drawingArea = new DrawingPanel();
		gameFrame.add(drawingArea, BorderLayout.CENTER);

		images = new Image[4];
		images[0] = new ImageIcon("images/pentagoMainBG.jpg").getImage();
		images[1] = new ImageIcon("images/boardBG.png").getImage();
		images[2] = new ImageIcon("images/playerConsole.png").getImage();
		images[3] = new ImageIcon("images/gameConsole.png").getImage();


		quads = new ImageIcon("images/Quadrant1&4BG.png").getImage();
		quads2 = new ImageIcon("images/Quadrant2&3BG.png").getImage();

		gameOverImages = new Image[5];
		
		gameOverImages[0] = new ImageIcon("images/black_wins.jpg").getImage();
		gameOverImages[1] = new ImageIcon("images/red_wins.jpg").getImage();
		gameOverImages[2] = new ImageIcon("images/draw.jpg").getImage();
		gameOverImages[3] = new ImageIcon("images/illegal_move.jpg").getImage();
		gameOverImages[4] = new ImageIcon("images/error.jpg").getImage();

		
		gameBoard = new Board(gameFrame);
		rotatingQuad = NO_ROTATING_QUAD;
		currentPlayer = BLACK;
		direction = RIGHT;

		gameStatus = "Game Initialized\n"+"Player One Play";

		needToRotate = false;
		angle = 0;
		
		addMenus();
		gameFrame.setVisible(true);

		gameLogic = new Pentagorun();
		gameLogic.startGame(mode);  // 1,2,3 depends on game mode (pvp,pvc,cvc)   ;    move first?
	}
	
  	public void showStatus(String nextMessage)
	{
		this.gameStatus = nextMessage;
	}

	public void addMenus()
	{
		JMenuBar menuBar = new JMenuBar();
		JMenu gameMenu = new JMenu("Game");

		JMenuItem newGameOption = new JMenuItem("New Game");
		newGameOption.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent event)
			{
				drawSettingsPanel();
				pvc.addActionListener(new ActionListener(){

					public void actionPerformed(ActionEvent e) {
						
						if(pvc.isSelected()){
							iaChoice.setVisible(true);
						}
						
					}
					
				});
				
				pvp.addActionListener(new ActionListener(){

					public void actionPerformed(ActionEvent e) {
						
						if(pvp.isSelected()){
							iaChoice.setVisible(false);
						}
						
					}
					
				});
				
				submitSettings.addActionListener(new ActionListener() {
					
					public void actionPerformed(ActionEvent e) {
						if(pvp.isSelected()){
							settings.setVisible(false);
							destroySettings();
							
						}else{
							int iaAlghoritm = iaChoice.getSelectedIndex();
							System.out.println(iaAlghoritm);
							settings.setVisible(false);
							destroySettings();
						}
						
						if(pvp.isSelected())
							mode = 1;
						else if(pvc.isSelected())
							mode = 2;
						else
							mode = 3;
						
						if(pvc.isSelected()){
							if(iaChoice.getSelectedIndex() == 1){}
								//setta algoritmo a minmax
							else{}
								//setta algoritmo a alfabeta pruning
						}
							
					}
				});
				
				exitSettings.addActionListener(new ActionListener() {
					
					public void actionPerformed(ActionEvent e) {
						settings.setVisible(false);
						destroySettings();
					}
				});

			}
		});

		JMenuItem exitGameOption = new JMenuItem("Exit");
		exitGameOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event)
			{

				if (gameOn)
				{
					if (gameType == 0)
					{ 
						int answer = JOptionPane
								.showConfirmDialog(
										null,
										"Are you sure you want to exit? ",
										"",
										JOptionPane.YES_NO_OPTION);
						if (answer == JOptionPane.YES_OPTION)
						{
							System.exit(0);
						}
					}
				}
				else
				{
					System.exit(0);
				}
			}
		});

		gameFrame.setJMenuBar(menuBar);
		menuBar.add(gameMenu);
		gameMenu.add(newGameOption);
		gameMenu.addSeparator();
		gameMenu.add(exitGameOption);
		
		

		
		JMenu helpMenu = new JMenu("Help");

		JMenuItem howToPlayOption = new JMenuItem("Rules");
		howToPlayOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evnt)
			{

			}
		});

		JMenuItem aboutOption = new JMenuItem("Credits");
		aboutOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evnt)
			{

			}
		});

		menuBar.add(helpMenu);
		helpMenu.add(howToPlayOption);
		helpMenu.addSeparator();
		helpMenu.add(aboutOption);

	}

	private class DrawingPanel extends JPanel
	{
		
		private static final long serialVersionUID = 1L;

		public DrawingPanel()
		{

			gameFrame.setResizable(true);
			setBackground(new Color(39, 33, 24));
			setPreferredSize(new Dimension(665, 600));

			this.addMouseListener(new MouseHandler());
			this.addMouseMotionListener(new MouseMotionHandler());

		}

		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			Graphics2D g2d = (Graphics2D) g;
			g2d.addRenderingHints(new RenderingHints(
					RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON));

			g2d.drawImage(images[0], 0, 0, 665, 368, this);
			g2d.drawImage(images[1], 33, 74, 390, 391, this);

			g2d.drawImage(images[2], 451, 74, 186, 187, this);

			g2d.drawImage(images[3], 451, 275, 186, 150, this);
		
			g2d.drawImage(quads, 45, 88, 177, 176, this);
			g2d.drawImage(quads2, 232, 88, 177, 176, this);
			g2d.drawImage(quads2, 45, 274, 177, 176, this);
			g2d.drawImage(quads, 232, 274, 177, 176, this);


			if (gameLogic.getGameStatus() == 0)
			{
				
				g2d.setFont(new Font("Tahoma", Font.BOLD, 14));
				g2d.setColor(new Color(39, 33, 24));

				
				g2d.drawString("Game Status:", 460, 315);
				
				g2d.setFont(new Font("Tahoma", Font.PLAIN, 11));

				g2d.drawString(gameStatus, 463, 330);
				
				g2d.setFont(new Font("Tahoma", Font.BOLD, 14));
				g2d.setColor(new Color(39, 33, 24));

				g2d.drawString("Rotation Count:", 460, 385);
				
				g2d.setFont(new Font("Tahoma", Font.PLAIN, 14));

				g2d.drawString(" " + (rotationCount), 575, 385);
				
				gameBoard.draw(g2d, rotatingQuad, angle);

			}else if(gameLogic.getGameStatus() == 99){
				g2d.drawImage(gameOverImages[errorIndexImage-1], 180, 500, 100,
						50, this);
			}else{
				g2d.drawImage(gameOverImages[gameLogic.getGameStatus()-1], 180, 500, 100,
						50, this);
			}

		}

	}

	private class MouseHandler extends MouseAdapter
	{
		public void mousePressed(MouseEvent event)
		{
			if (gameLogic.getGameStatus()==0)
				{
					if (!needToRotate){
					Point p = gameBoard.makeMove(event.getPoint(),currentPlayer);
					}
					
					needToRotate = true;
					gameFrame.repaint();

				}
					else{
						if (currentPlayer == BLACK)
							gameStatus = "Player One" + " please rotate...";
						else
							gameStatus = "Player Two" + " please rotate...";
						
						rotatingQuad = gameBoard.selectedQuadrant(event
								.getPoint());
				}
			
		


			start = event.getPoint();
			gameFrame.repaint();

		}

		public void mouseReleased(MouseEvent event)
		{
			if (gameLogic.getGameStatus() == 0)
			{
				if (!needToRotate)
				{
					
						if (currentPlayer == BLACK)
							gameStatus = "Player One"
									+ " please make a move...";
						else
							gameStatus = "Player Two"
									+ " please make a move...";

					if (gameBoard.isFilled(event.getPoint()))
						gameStatus = "That spot is already taken!";
				}
			}

			rotatingQuad = -1;
			angle = 0;
			gameFrame.repaint();
		}

	}

	private class MouseMotionHandler extends MouseMotionAdapter
	{
		public void mouseMoved(MouseEvent event)
		{
			if (gameLogic.getGameStatus() == 0)
			{
				//gameBoard.showCurrentPos(event.getPoint());
				gameFrame.repaint();
			}
		}

		public void mouseDragged(MouseEvent event)
		{
			if (gameLogic.getGameStatus() == 0)
			{
				if (rotatingQuad == NO_ROTATING_QUAD)
					return;

				if (needToRotate)
				{
					Point centre = gameBoard.getCentre(rotatingQuad);

					int firstX = start.x - centre.x;
					int firstY = start.y - centre.y;

					double firstAngle = (Math.toRadians(Math.atan2(firstY,
							firstX)));
					Point end = event.getPoint();

					int lastX = end.x - centre.x;
					int lastY = end.y - centre.y;

					double lastAngle = (Math
							.toRadians(Math.atan2(lastY, lastX)));

					if (gameLogic.getGameStatus() == 0)
					{
						if (lastAngle > firstAngle)
						{
							angle += 8;
							direction = RIGHT;
						}
						else
						{
							angle -= 8;
							direction = LEFT;
						}
					}


					if (angle >= 90)
					{
						angle = 90;
						//gameBoard.rotate(rotatingQuad, direction);

						rotatingQuad = NO_ROTATING_QUAD;

						needToRotate = false;

						rotationCount++;
						gameFrame.repaint();

					}
					else if (angle <= -90)
					{
						angle = -90;
						//gameBoard.rotate(rotatingQuad, direction);

						rotatingQuad = NO_ROTATING_QUAD;

						needToRotate = false;

						rotationCount++;
						gameFrame.repaint();
					}

					start = event.getPoint();
					gameFrame.repaint();
				}
			}
		}
	}

	public void endGame(boolean tie, boolean tie2, boolean currentPlayer)
	{
		gameFrame.repaint();
		gameOver = true;

		if (tie || tie2)
		{
			gameStatus = "Tie Game!";
			gameEndStatus = 2;
		}
		else if (!tie && !tie2)
		{

			if (currentPlayer == BLACK)
			{
				gameStatus = "Player Two" + " has Won the Game!";

			}
			else
			{
				gameStatus = "Player One" + " has Won the Game!";

				gameEndStatus = 0;

			}
			
		}
		gameFrame.repaint();
	}
	
	
	private void drawSettingsPanel(){
		settings = new JFrame("Game Settings");
		settings.setLayout(new GridLayout(2, 0));
		settings.setSize(400, 400);
		
		choicePan = new JPanel();
		choicePan.setLayout(new GridLayout(2,0));
		buttonPan = new JPanel();
		choice = new ButtonGroup();
		pvp = new JRadioButton("Player vs Player");
		pvc = new JRadioButton("Player vs IA Player");
		cvc = new JRadioButton("IA Player vs IA Player");
		
		iaChoice = new JComboBox<String>(gameMode);
		iaChoice.setVisible(false);
		submitSettings = new JButton("Submit");
		exitSettings = new JButton ("Cancel");
		

		choice.add(pvp);
		choice.add(pvc);
		choice.add(cvc);

		choicePan.add(pvp);
		choicePan.add(pvc);
		choicePan.add(cvc);
		choicePan.add(iaChoice,2);
		
		buttonPan.add(submitSettings);
		buttonPan.add(exitSettings);
		
		settings.add(choicePan);
		settings.add(buttonPan);
		settings.setVisible(true);
	}
	
	private void destroySettings(){
		settings = null;
		choicePan = null;
		buttonPan = null;
		choice = null;
		pvp = null;
		pvc = null;
		cvc=null;
		iaChoice = null;
		submitSettings = null;
		exitSettings = null;
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		
	}
}
